package providers

import (
	"context"
	"fmt"
	"regexp"
	"strings"
	"time"
)

// SMSProvider SMS提供商接口
type SMSProvider interface {
	// GetName 获取提供商名称
	GetName() string

	// SendSMS 发送单条短信
	SendSMS(ctx context.Context, req *SendSMSRequest) (*SendSMSResponse, error)

	// SendBatchSMS 批量发送短信
	SendBatchSMS(ctx context.Context, req *BatchSMSRequest) (*BatchSMSResponse, error)

	// QuerySMS 查询短信状态
	QuerySMS(ctx context.Context, req *QuerySMSRequest) (*QuerySMSResponse, error)

	// GetQuota 获取剩余配额
	GetQuota(ctx context.Context) (*QuotaResponse, error)

	// ValidateConfig 验证配置
	ValidateConfig() error

	// HealthCheck 健康检查
	HealthCheck(ctx context.Context) error
}

// SendSMSRequest 发送短信请求
type SendSMSRequest struct {
	Phone     string            `json:"phone"`               // 手机号
	Content   string            `json:"content"`             // 短信内容
	Sign      string            `json:"sign,omitempty"`      // 短信签名
	Type      string            `json:"type,omitempty"`      // 短信类型
	Priority  int               `json:"priority,omitempty"`  // 优先级
	Scheduled *time.Time        `json:"scheduled,omitempty"` // 定时发送时间
	Metadata  map[string]string `json:"metadata,omitempty"`  // 元数据
	MessageID string            `json:"message_id"`          // 消息ID
}

// SendSMSResponse 发送短信响应
type SendSMSResponse struct {
	MessageID    string            `json:"message_id"`         // 消息ID
	Status       string            `json:"status"`             // 状态
	ProviderID   string            `json:"provider_id"`        // 提供商消息ID
	Cost         float64           `json:"cost,omitempty"`     // 费用
	SentAt       time.Time         `json:"sent_at"`            // 发送时间
	DeliveredAt  *time.Time        `json:"delivered_at,omitempty"` // 送达时间
	ErrorCode    string            `json:"error_code,omitempty"`   // 错误代码
	ErrorMessage string            `json:"error_message,omitempty"` // 错误消息
	Metadata     map[string]string `json:"metadata,omitempty"`     // 元数据
}

// BatchSMSRequest 批量发送短信请求
type BatchSMSRequest struct {
	Requests []*SendSMSRequest `json:"requests"` // 短信请求列表
	BatchID  string            `json:"batch_id"` // 批次ID
}

// BatchSMSResponse 批量发送短信响应
type BatchSMSResponse struct {
	BatchID    string               `json:"batch_id"`    // 批次ID
	Total      int                  `json:"total"`       // 总数
	Success    int                  `json:"success"`     // 成功数
	Failed     int                  `json:"failed"`      // 失败数
	Results    []*BatchSMSResult    `json:"results"`     // 结果列表
	StartedAt  time.Time            `json:"started_at"`  // 开始时间
	FinishedAt time.Time            `json:"finished_at"` // 完成时间
	Cost       float64              `json:"cost"`        // 总费用
}

// BatchSMSResult 批量发送结果
type BatchSMSResult struct {
	Index        int                `json:"index"`               // 索引
	Phone        string             `json:"phone"`               // 手机号
	MessageID    string             `json:"message_id,omitempty"` // 消息ID
	ProviderID   string             `json:"provider_id,omitempty"` // 提供商消息ID
	Status       string             `json:"status"`              // 状态
	Cost         float64            `json:"cost,omitempty"`      // 费用
	SentAt       *time.Time         `json:"sent_at,omitempty"`   // 发送时间
	ErrorCode    string             `json:"error_code,omitempty"` // 错误代码
	ErrorMessage string             `json:"error_message,omitempty"` // 错误消息
}

// QuerySMSRequest 查询短信状态请求
type QuerySMSRequest struct {
	MessageID  string `json:"message_id,omitempty"`  // 消息ID
	ProviderID string `json:"provider_id,omitempty"` // 提供商消息ID
	Phone      string `json:"phone,omitempty"`       // 手机号
}

// QuerySMSResponse 查询短信状态响应
type QuerySMSResponse struct {
	MessageID    string            `json:"message_id"`              // 消息ID
	ProviderID   string            `json:"provider_id"`             // 提供商消息ID
	Phone        string            `json:"phone"`                   // 手机号
	Content      string            `json:"content"`                 // 短信内容
	Status       string            `json:"status"`                  // 状态
	SentAt       *time.Time        `json:"sent_at,omitempty"`       // 发送时间
	DeliveredAt  *time.Time        `json:"delivered_at,omitempty"`  // 送达时间
	FailedAt     *time.Time        `json:"failed_at,omitempty"`     // 失败时间
	ErrorCode    string            `json:"error_code,omitempty"`    // 错误代码
	ErrorMessage string            `json:"error_message,omitempty"` // 错误消息
	Cost         float64           `json:"cost,omitempty"`          // 费用
	Metadata     map[string]string `json:"metadata,omitempty"`      // 元数据
}

// QuotaResponse 配额响应
type QuotaResponse struct {
	Total     int64     `json:"total"`     // 总配额
	Used      int64     `json:"used"`      // 已使用
	Remaining int64     `json:"remaining"` // 剩余
	ResetAt   time.Time `json:"reset_at"`  // 重置时间
}

// ProviderError 提供商错误
type ProviderError struct {
	Code     string `json:"code"`     // 错误代码
	Message  string `json:"message"`  // 错误消息
	Provider string `json:"provider"` // 提供商
	Retryable bool  `json:"retryable"` // 是否可重试
}

// Error 实现error接口
func (e *ProviderError) Error() string {
	return fmt.Sprintf("[%s] %s: %s", e.Provider, e.Code, e.Message)
}

// IsRetryable 是否可重试
func (e *ProviderError) IsRetryable() bool {
	return e.Retryable
}

// ProviderFactory 提供商工厂接口
type ProviderFactory interface {
	// CreateProvider 创建提供商实例
	CreateProvider(providerType string, config interface{}) (SMSProvider, error)

	// GetSupportedProviders 获取支持的提供商列表
	GetSupportedProviders() []string

	// ValidateProviderConfig 验证提供商配置
	ValidateProviderConfig(providerType string, config interface{}) error
}

// BaseProvider 基础提供商实现
type BaseProvider struct {
	name    string
	timeout time.Duration
}

// GetName 获取提供商名称
func (p *BaseProvider) GetName() string {
	return p.name
}

// SetTimeout 设置超时时间
func (p *BaseProvider) SetTimeout(timeout time.Duration) {
	p.timeout = timeout
}

// GetTimeout 获取超时时间
func (p *BaseProvider) GetTimeout() time.Duration {
	if p.timeout == 0 {
		return 30 * time.Second // 默认30秒
	}
	return p.timeout
}

// ValidateRequest 验证请求参数
func (p *BaseProvider) ValidateRequest(req *SendSMSRequest) error {
	if req == nil {
		return &ProviderError{
			Code:     "INVALID_REQUEST",
			Message:  "请求不能为空",
			Provider: p.name,
			Retryable: false,
		}
	}

	if req.Phone == "" {
		return &ProviderError{
			Code:     "INVALID_PHONE",
			Message:  "手机号不能为空",
			Provider: p.name,
			Retryable: false,
		}
	}

	if req.Content == "" {
		return &ProviderError{
			Code:     "INVALID_CONTENT",
			Message:  "短信内容不能为空",
			Provider: p.name,
			Retryable: false,
		}
	}

	return nil
}

// ValidateBatchRequest 验证批量请求参数
func (p *BaseProvider) ValidateBatchRequest(req *BatchSMSRequest) error {
	if req == nil {
		return &ProviderError{
			Code:     "INVALID_REQUEST",
			Message:  "批量请求不能为空",
			Provider: p.name,
			Retryable: false,
		}
	}

	if len(req.Requests) == 0 {
		return &ProviderError{
			Code:     "EMPTY_BATCH",
			Message:  "批量请求列表不能为空",
			Provider: p.name,
			Retryable: false,
		}
	}

	for i, smsReq := range req.Requests {
		if err := p.ValidateRequest(smsReq); err != nil {
			return &ProviderError{
				Code:     "INVALID_BATCH_ITEM",
				Message:  fmt.Sprintf("第%d项请求无效: %s", i+1, err.Error()),
				Provider: p.name,
				Retryable: false,
			}
		}
	}

	return nil
}

// CreateProviderError 创建提供商错误
func (p *BaseProvider) CreateProviderError(code, message string, retryable bool) *ProviderError {
	return &ProviderError{
		Code:     code,
		Message:  message,
		Provider: p.name,
		Retryable: retryable,
	}
}

// FormatPhone 格式化手机号
func FormatPhone(phone string) string {
	// 去除空格和特殊字符
	phone = strings.ReplaceAll(phone, " ", "")
	phone = strings.ReplaceAll(phone, "-", "")
	phone = strings.ReplaceAll(phone, "(", "")
	phone = strings.ReplaceAll(phone, ")", "")

	// 如果是中国大陆手机号，确保以+86开头
	if matched, _ := regexp.MatchString(`^1[3-9]\d{9}$`, phone); matched {
		if !strings.HasPrefix(phone, "+86") {
			phone = "+86" + phone
		}
	}

	return phone
}

// EstimateCost 估算费用
func EstimateCost(content string, smsType string) float64 {
	length := len([]rune(content))
	baseCost := 0.05 // 基础费用5分

	// 根据长度计算费用
	if length > 70 {
		baseCost *= float64((length-1)/70 + 1) // 超过70字符按条数计费
	}

	// 根据类型调整费用
	switch smsType {
	case "marketing":
		baseCost *= 1.2 // 营销短信费用更高
	case "international":
		baseCost *= 3.0 // 国际短信费用更高
	}

	return baseCost
}